package com.example.linphone_flutter;

import org.linphone.core.Account;
import org.linphone.core.AudioDevice;
import org.linphone.core.Call;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatRoom;
//import org.linphone.core.ChatRoomCapabilities;
import org.linphone.core.Content;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.RegistrationState;

import java.util.HashMap;
import java.util.Map;

import io.flutter.plugin.common.BinaryMessenger;
import io.flutter.plugin.common.EventChannel;

public class LinphoneListener extends CoreListenerStub implements EventChannel.StreamHandler {
    private EventChannel eventChannel;
    private EventChannel.EventSink eventSink;

    LinphoneListener(BinaryMessenger messenger) {
        eventChannel = new EventChannel(messenger, "linphone_flutter/core");
        eventChannel.setStreamHandler(this);
    }

    @Override
    public void onAccountRegistrationStateChanged(Core core, Account account, RegistrationState state, String message) {
        if (eventSink != null) {
            Map<String, Object> res = new HashMap();
            res.put("type", "connected");
            if (state == RegistrationState.Failed || state == RegistrationState.Cleared) {
                core.clearAllAuthInfo();
                core.clearAccounts();
                res.put("result", false);
                eventSink.success(res);
            } else if (state == RegistrationState.Ok) {
                res.put("result", true);
                eventSink.success(res);
            }
        }
    }

    @Override
    public void onAudioDeviceChanged(Core core, AudioDevice audioDevice) {

    }

    @Override
    public void onAudioDevicesListUpdated(Core core) {

    }

    @Override
    public void onCallStateChanged(Core core, Call call, Call.State state, String message) {
        if (eventSink != null) {
            if (state == Call.State.IncomingReceived) {
                CallStateChange("IncomingReceived", message);
            } else if (state == Call.State.Connected) {
                CallStateChange("Connected", message);
            } else if (state == Call.State.Released) {
                CallStateChange("Released", message);
            } else if (state == Call.State.OutgoingInit) {
                CallStateChange("OutgoingInit", message);
            } else if (state == Call.State.OutgoingProgress) {
                CallStateChange("OutgoingProgress", message);
            } else if (state == Call.State.OutgoingRinging) {
                CallStateChange("OutgoingRinging", message);
            } else if (state == Call.State.StreamsRunning) {
                CallStateChange("StreamsRunning", message);
            } else if (state == Call.State.Paused) {
                CallStateChange("Paused", message);
            } else if (state == Call.State.PausedByRemote) {
                CallStateChange("PausedByRemote", message);
            } else if (state == Call.State.Updating) {
                CallStateChange("Updating", message);
            } else if (state == Call.State.UpdatedByRemote) {
                CallStateChange("UpdatedByRemote", message);
            } else if (state == Call.State.Error) {
                CallStateChange("Error", message);
            }
        }
    }

    public void CallStateChange(String stateString, String message) {
        Map<String, Object> res = new HashMap();
        res.put("type", "CallState");
        res.put("result", stateString);
        res.put("message", message);
        eventSink.success(res);
    }

    @Override
    public void onMessageReceived(Core core, ChatRoom chatRoom, ChatMessage message) {
        if (ChatMessageManager.chatRoom == null) {
            if (chatRoom.hasCapability(ChatRoom.Capabilities.OneToOne.toInt()) &&
                    chatRoom.hasCapability(ChatRoom.Capabilities.Encrypted.toInt())) {
                ChatMessageManager.chatRoom = chatRoom;
            }
        }
        chatRoom.markAsRead();
        addMessageToHistory(message);
    }


    void addMessageToHistory(ChatMessage chatMessage) {
        for (Content content : chatMessage.getContents()) {
            if (content.isText()) {
                addTextMessageToHistory(chatMessage, content);
            }
        }
    }

    void addTextMessageToHistory(ChatMessage chatMessage, Content content) {
        Map<String, Object> res = new HashMap();
        res.put("type", "onMessageReceived");
        res.put("result", content.getUtf8Text());
        eventSink.success(res);
    }

    void addDownloadButtonToHistory(ChatMessage chatMessage, Content content) {
    }

    void addImageMessageToHistory(ChatMessage chatMessage, Content content) {

    }


    @Override
    public void onListen(Object arguments, EventChannel.EventSink events) {
        this.eventSink = events;
    }

    @Override
    public void onCancel(Object arguments) {
        this.eventSink = null;
    }
}
